﻿using System;
using System.Collections.Generic;
using System.Text;
using VCDIFF.Visit;

namespace VCDIFF.Commands
{
    ///<summary>
    /// COPY: This instruction has two arguments, a size x and an address
    /// p in the string U. The arguments specify the substring of U
    /// that must be copied. We shall assert that such a substring
    /// must be entirely contained in either source or target window.
    ///</summary>
    public class Copy : Command
    {

        public SourceFile Source { get; set; }
        public UInt64 Address { get; set; }
        public UInt64 Size { get; set; }

        /// <summary>
        /// Copy constructor.
        /// </summary>
        /// <param name="size">Size of data to copy.</param>
        /// <param name="address">Address where the copy start.</param>
        /// <param name="source">Source data for the copy.</param>
        public Copy(UInt64 size, UInt64 address, SourceFile source)
        {
            Size = size;
            Address = address;
            Source = source;
        }

        /// <summary>
        /// Execute the copy command on the source byte table.
        /// </summary>
        /// <param name="target">Byte table on which we proceed the command.</param>
        /// <returns>Byte table on which the command was done.</returns>
        public override byte[] Execute(byte[] target)
        {
            byte[] copyArray = new byte[(UInt64)target.Length + Size];

            int index = 0;

            for (int i = 0; i < target.Length; i++)
            {
                copyArray[i] = target[i];
                index++;
            }

            for (UInt64 i = Address; i < Address + Size; i++)
            {
                copyArray[index] = Source.Source[i];
                index++;
            }
                        
            return copyArray;
        }

        /// <summary>
        /// Returns the encoded byte table of the copy command.
        /// </summary>
        /// <returns>The encoded byte table of the copy command.</returns>
        public override byte[] ToByteArray()
        {
            return new byte[3] { 0x03, Convert.ToByte(Size), Convert.ToByte(Address) };
        }

        /// <summary>
        /// Writes Copy command thanks to a Writer.
        /// </summary>
        /// <param name="writer">Writer who writes Copy command.</param>
        public override void Write(Writer writer)
        {
            writer.Visit(this);
        }

        /// <summary>
        /// Accepts a reader and authorizes it to visit this object.
        /// </summary>
        /// <param name="writer">Reader which visits this object.</param>
        public override void Read(Reader reader)
        {
            reader.Visit(this);
        }
    }
}
